﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Microsoft.VisualBasic;
using Microsoft.VisualBasic.CompilerServices;

namespace ConvertPlist
{
    public class ConvertPlist
    {
        private ConvertPlist() { }

        public static string plist2xml(string SourcePlistFileName)
        {
            if (!File.Exists(SourcePlistFileName))
            {
                return "NoSource";
            }
            FileStream stream = new FileStream(SourcePlistFileName, FileMode.Open);
            return plist2xml(stream);
        }

        private static string plist2xml(Stream stream)
        {
            int index = 0;
            string str6 = "";
            string str = "";
            int[] numArray = ReadStream2Array(stream);

            long length = numArray.LongLength;
            int num8 = 0;
            int num9 = 0;
            int num10 = 0;
            int number = 0;
            int num13 = 0;
            int charCode = 0;
            int num15 = 0;
            string left = "";
            string str8 = "";
            string str9 = "";
            string[] strArray = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,0,1,2,3,4,5,6,7,8,9,+,/".Split(new char[] { ',' });

            int num11 = numArray[(int)(length - 0x1aL)];
            int num16 = numArray[(int)(length - 0x19L)];
            string str10 = "";
            int num7 = 0;
            int num5 = 0;
            int num6 = 0;
            int num2 = 0;
            int num3 = 0;
            string str2 = Conversion.Hex(numArray[8]);
            string str3 = "\n";
            string find = "\x0001";

            if (numArray.GetUpperBound(0) < 10)
            {
                return "NoPlistFile";
            }
            index = 0;
            do
            {
                str6 = str6 + Conversions.ToString(Strings.Chr(numArray[index]));
                index++;
            }
            while (index <= 7);
            if (Strings.InStr(str6, "<?xml", CompareMethod.Binary) > 0)
            {
                StreamReader reader = new StreamReader(stream);
                str = reader.ReadToEnd();
                stream.Close();
                reader.Close();
                return str;
            }
            if (str6 != "bplist00")
            {
                return "NoPlistFile";
            }

            
            if (Strings.Mid(str2, 1, 1) == "D")
            {
                str10 = "<dict>" + str3;
            }
            else if (Strings.Mid(str2, 1, 1) == "A")
            {
                str10 = "<array>" + str3;
            }
            else
            {
                return "StructureError";
            }
            if (Strings.Mid(Conversions.ToString(2), 1, 1) != "F")
            {
                num5 = Convert.ToInt32(Strings.Mid(str2, 2, 1), 0x10);
                num3 = 9;
            }
            else
            {
                num8 = numArray[10];
                int num22 = num11 - 2;
                for (index = 1; index <= num22; index++)
                {
                    num8 = (num8 * 0x100) + numArray[10 + index];
                }
                num5 = num8;
                num3 = 9 + num11;
            }
            num8 = 0;
            index = 0;
            do
            {
                num8 = (num8 * 0x100) + numArray[(int)((length + index) - 0x18L)];
                index++;
            }
            while (index <= 7);
            num7 = num8;
            num6 = (num8 - num5) - 1;
            num8 = 0;
            index = 0;
            do
            {
                num8 = (num8 * 0x100) + numArray[(int)((length + index) - 8L)];
                index++;
            }
            while (index <= 7);
            num2 = num8;
            string[,] strArray2 = new string[(num7 - 1) + 1, 3];
            for (index = num7 - 1; index >= 0; index += -1)
            {
                num9 = 0;
                int num23 = num11 - 1;
                num8 = 0;
                while (num8 <= num23)
                {
                    num9 = (num9 * 0x100) + numArray[(num2 + (index * num11)) + num8];
                    num8++;
                }
                num10 = num9;
                num9 = numArray[num9];
                str6 = Conversions.ToString(Interaction.IIf(num9 < 0x10, "0" + Conversion.Hex(num9), Conversion.Hex(num9)));
                strArray2[index, 0] = Conversions.ToString(index);
                switch (str6)
                {
                    case "08":
                        strArray2[index, 1] = "false";
                        strArray2[index, 2] = "false";
                        break;

                    case "09":
                        strArray2[index, 1] = "true";
                        strArray2[index, 2] = "true";
                        break;

                    case "10":
                        strArray2[index, 1] = "integer";
                        strArray2[index, 2] = Conversions.ToString(numArray[num10 + 1]);
                        break;

                    case "11":
                        strArray2[index, 1] = "integer";
                        strArray2[index, 2] = Conversions.ToString((int)((numArray[num10 + 1] * 0x100) + numArray[num10 + 1]));
                        break;

                    case "12":
                        strArray2[index, 1] = "integer";
                        strArray2[index, 2] = Conversions.ToString((int)((((((numArray[num10 + 1] * 0x100) + numArray[num10 + 2]) * 0x100) + numArray[num10 + 3]) * 0x100) + numArray[num10 + 4]));
                        break;

                    case "13":
                        strArray2[index, 1] = "integer";
                        left = "";
                        charCode = 1;
                        do
                        {
                            number = numArray[num10 + charCode];
                            left = Conversions.ToString(Operators.ConcatenateObject(left, Interaction.IIf(number < 0x10, "0" + Conversion.Hex(number), Conversion.Hex(number))));
                            charCode++;
                        }
                        while (charCode <= 8);
                        strArray2[index, 2] = Conversions.ToString((long)(Convert.ToInt64("FFFFFFFFFFFFFFFF", 0x10) & Convert.ToInt64(left, 0x10)));
                        break;

                    default:
                        if (Strings.Mid(str6, 1, 1) == "2")
                        {
                            strArray2[index, 1] = "real";
                            charCode = 0;
                            if (Strings.Mid(str6, 2, 1) == "2")
                            {
                                charCode = 4;
                                byte[] buffer = new byte[] { (byte)numArray[num10 + 4], (byte)numArray[num10 + 3], (byte)numArray[num10 + 2], (byte)numArray[num10 + 1] };
                                strArray2[index, 2] = Conversions.ToString(BitConverter.ToSingle(buffer, 0));
                            }
                            else
                            {
                                charCode = 8;
                                str8 = "";
                                int num24 = charCode;
                                num13 = 1;
                                while (num13 <= num24)
                                {
                                    num15 = numArray[num10 + num13];
                                    str8 = Conversions.ToString(Operators.ConcatenateObject(str8, Interaction.IIf(num15 < 0x10, "0" + Conversion.Hex(num15), Conversion.Hex(num15))));
                                    num13++;
                                }
                                long num17 = Convert.ToInt64(str8, 0x10);
                                strArray2[index, 2] = Conversions.ToString(BitConverter.Int64BitsToDouble(num17));
                            }
                        }
                        else if (str6 == "33")
                        {
                            DateTime time = new DateTime(0x851055b821ba800L);
                            long num18 = 0x40140b8e20L;
                            long num19 = 0L;
                            charCode = 1;
                            do
                            {
                                num19 = (num19 * 0x100L) + numArray[num10 + charCode];
                                charCode++;
                            }
                            while (charCode <= 5);
                            num19 = (long)Math.Round((double)(((double)(num19 - num18)) / 2.0));
                            time = time.AddSeconds((double)num19);
                            strArray2[index, 1] = "date";
                            strArray2[index, 2] = time.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'");
                        }
                        else if (Strings.Mid(str6, 1, 1) == "4")
                        {
                            if (Strings.Mid(str6, 2, 1) != "F")
                            {
                                number = 1;
                                num13 = Convert.ToInt32(Strings.Mid(str6, 2, 1), 0x10);
                            }
                            else
                            {
                                num13 = 0;
                                int num25 = numArray[num10 + 1] - 0x10;
                                charCode = 0;
                                while (charCode <= num25)
                                {
                                    num13 = (num13 * 0x100) + numArray[(num10 + 2) + charCode];
                                    charCode++;
                                }
                                number = (3 + numArray[num10 + 1]) - 0x10;
                            }
                            left = "";
                            str8 = "";
                            int num26 = num13 - 1;
                            num8 = 0;
                            while (num8 <= num26)
                            {
                                charCode = numArray[(num10 + number) + num8];
                                left = left + Conversions.ToString(Strings.Chr(charCode));
                                num8++;
                            }
                            strArray2[index, 1] = "data";
                            str9 = "";
                            str8 = "";
                            charCode = left.Length % 3;
                            if (charCode > 0)
                            {
                                if (charCode == 1)
                                {
                                    str8 = "==";
                                    left = left + "\0\0";
                                }
                                else
                                {
                                    str8 = "=";
                                    left = left + "\0";
                                }
                            }
                            int num27 = num13 - 1;
                            number = 0;
                            while (number <= num27)
                            {
                                if ((number > 0) & ((((((double)number) / 3.0) * 4.0) % 68.0) == 0.0))
                                {
                                    str9 = str9 + "\n";
                                }
                                int num20 = ((Strings.Asc(Strings.Mid(left, number + 1, 1)) << 0x10) + (Strings.Asc(Strings.Mid(left, number + 2, 1)) << 8)) + Strings.Asc(Strings.Mid(left, number + 3, 1));
                                byte[] buffer2 = new byte[] { (byte)(num20 >> 0x12), (byte)(((long)Math.Round((double)(((double)num20) % 262144.0))) >> 12), (byte)(((long)Math.Round((double)(((double)num20) % 4096.0))) >> 6), (byte)Math.Round((double)(((double)num20) % 64.0)) };
                                str9 = str9 + strArray[buffer2[0]] + strArray[buffer2[1]] + strArray[buffer2[2]] + strArray[buffer2[3]];
                                number += 3;
                            }
                            str9 = Strings.Mid(str9, 1, str9.Length - str8.Length) + str8;
                            strArray2[index, 2] = str9;
                        }
                        else if ((Strings.Mid(str6, 1, 1) != "D") && (Strings.Mid(str6, 1, 1) != "A"))
                        {
                            if (Strings.Mid(str6, 1, 1) == "5")
                            {
                                if (Strings.Mid(str6, 2, 1) != "F")
                                {
                                    number = 1;
                                    num13 = Convert.ToInt32(Strings.Mid(str6, 2, 1), 0x10);
                                }
                                else
                                {
                                    num13 = 0;
                                    int num28 = numArray[num10 + 1] - 0x10;
                                    charCode = 0;
                                    while (charCode <= num28)
                                    {
                                        num13 = (num13 * 0x100) + numArray[(num10 + 2) + charCode];
                                        charCode++;
                                    }
                                    number = (3 + numArray[num10 + 1]) - 0x10;
                                }
                                left = "";
                                str8 = "";
                                int num29 = num13 - 1;
                                num8 = 0;
                                while (num8 <= num29)
                                {
                                    charCode = numArray[(num10 + number) + num8];
                                    left = left + Conversions.ToString(Strings.Chr(charCode));
                                    num8++;
                                }
                                strArray2[index, 1] = "string";
                                strArray2[index, 2] = fixXMLString(left);
                            }
                            else
                            {
                                if (Strings.Mid(str6, 1, 1) != "6")
                                {
                                    return "UnkownElement";
                                }
                                if (Strings.Mid(str6, 2, 1) != "F")
                                {
                                    number = 1;
                                    num13 = Convert.ToInt32(Strings.Mid(str6, 2, 1), 0x10);
                                }
                                else
                                {
                                    num13 = 0;
                                    int num30 = numArray[num10 + 1] - 0x10;
                                    charCode = 0;
                                    while (charCode <= num30)
                                    {
                                        num13 = (num13 * 0x100) + numArray[(num10 + 2) + charCode];
                                        charCode++;
                                    }
                                    number = 3 + (numArray[num10 + 1] - 0x10);
                                }
                                left = "";
                                str8 = "";
                                int num31 = num13 - 1;
                                num8 = 0;
                                while (num8 <= num31)
                                {
                                    charCode = numArray[(num10 + number) + (num8 * 2)];
                                    num15 = numArray[((num10 + number) + (num8 * 2)) + 1];
                                    left = left + Conversions.ToString(Strings.ChrW((charCode * 0x100) + num15));
                                    str8 = Conversions.ToString(Operators.ConcatenateObject(Operators.ConcatenateObject(str8, Interaction.IIf(charCode < 0x10, "0" + Conversion.Hex(charCode), Conversion.Hex(charCode))), Interaction.IIf(num15 < 0x10, "0" + Conversion.Hex(num15), Conversion.Hex(num15))));
                                    num8++;
                                }
                                strArray2[index, 1] = "string";
                                strArray2[index, 2] = fixXMLString(left);
                            }
                        }
                        break;
                }
            }
            for (index = num7 - 1; index >= 0; index += -1)
            {
                num9 = 0;
                int num32 = num11 - 1;
                num8 = 0;
                while (num8 <= num32)
                {
                    num9 = (num9 * 0x100) + numArray[(num2 + (index * num11)) + num8];
                    num8++;
                }
                num10 = num9;
                num9 = numArray[num9];
                str6 = Conversions.ToString(Interaction.IIf(num9 < 0x10, "0" + Conversion.Hex(num9), Conversion.Hex(num9)));
                strArray2[index, 0] = Conversions.ToString(index);
                if ((((str6 != "08") && (str6 != "09")) && ((str6 != "10") && (str6 != "11"))) && (((str6 != "12") && (str6 != "13")) && (Strings.Mid(str6, 1, 1) != "2")))
                {
                    if (Strings.Mid(str6, 1, 1) == "D")
                    {
                        if (Strings.Mid(str6, 2, 1) != "F")
                        {
                            number = 1;
                            num13 = Convert.ToInt32(Strings.Mid(str6, 2, 1), 0x10);
                        }
                        else
                        {
                            num13 = 0;
                            int num33 = numArray[num10 + 1] - 0x10;
                            charCode = 0;
                            while (charCode <= num33)
                            {
                                num13 = (num13 * 0x100) + numArray[(num10 + 2) + charCode];
                                charCode++;
                            }
                            number = (3 + numArray[num10 + 1]) - 0x10;
                        }
                        left = "";
                        str8 = "";
                        left = left + find + "<dict>" + str3;
                        int num34 = num13 - 1;
                        num8 = 0;
                        while (num8 <= num34)
                        {
                            charCode = 0;
                            num15 = 0;
                            int num35 = num16 - 1;
                            num15 = 0;
                            while (num15 <= num35)
                            {
                                charCode = (charCode * 0x100) + numArray[((num10 + number) + (num8 * num16)) + num15];
                                num15++;
                            }
                            str8 = find + find + "<key>" + strArray2[charCode, 2] + "</key>" + str3;
                            left = left + str8;
                            charCode = 0;
                            int num36 = num16 - 1;
                            num15 = 0;
                            while (num15 <= num36)
                            {
                                charCode = (charCode * 0x100) + numArray[((num10 + number) + ((num13 + num8) * num16)) + num15];
                                num15++;
                            }
                            if ((strArray2[charCode, 1] == "true") | (strArray2[charCode, 1] == "false"))
                            {
                                str8 = find + find + "<" + strArray2[charCode, 1] + "/>" + str3;
                            }
                            else if ((strArray2[charCode, 1] == "dict") | (strArray2[charCode, 1] == "array"))
                            {
                                str8 = Strings.Replace(strArray2[charCode, 2], find + "<", find + find + "<", 1, -1, CompareMethod.Binary);
                            }
                            else
                            {
                                str8 = find + find + "<" + strArray2[charCode, 1] + ">" + strArray2[charCode, 2] + "</" + strArray2[charCode, 1] + ">" + str3;
                            }
                            left = left + str8;
                            num8++;
                        }
                        left = left + find + "</dict>" + str3;
                        strArray2[index, 1] = "dict";
                        strArray2[index, 2] = left;
                    }
                    else if (Strings.Mid(str6, 1, 1) == "A")
                    {
                        if (Strings.Mid(str6, 2, 1) != "F")
                        {
                            number = 1;
                            num13 = Convert.ToInt32(Strings.Mid(str6, 2, 1), 0x10);
                        }
                        else
                        {
                            num13 = 0;
                            int num37 = numArray[num10 + 1] - 0x10;
                            charCode = 0;
                            while (charCode <= num37)
                            {
                                num13 = (num13 * 0x100) + numArray[(num10 + 2) + charCode];
                                charCode++;
                            }
                            number = (3 + numArray[num10 + 1]) - 0x10;
                        }
                        left = "";
                        str8 = "";
                        left = left + find + "<array>" + str3;
                        int num38 = num13 - 1;
                        for (num8 = 0; num8 <= num38; num8++)
                        {
                            charCode = 0;
                            int num39 = num16 - 1;
                            for (num15 = 0; num15 <= num39; num15++)
                            {
                                charCode = (charCode * 0x100) + numArray[((num10 + number) + (num8 * num16)) + num15];
                            }
                            if ((strArray2[charCode, 1] == "true") | (strArray2[charCode, 1] == "false"))
                            {
                                str8 = find + find + "<" + strArray2[charCode, 1] + "/>" + str3;
                            }
                            else if ((strArray2[charCode, 1] == "dict") | (strArray2[charCode, 1] == "array"))
                            {
                                str8 = Strings.Replace(strArray2[charCode, 2], find + "<", find + find + "<", 1, -1, CompareMethod.Binary);
                            }
                            else
                            {
                                str8 = find + find + "<" + strArray2[charCode, 1] + ">" + strArray2[charCode, 2] + "</" + strArray2[charCode, 1] + ">" + str3;
                            }
                            left = left + str8;
                        }
                        left = left + find + "</array>" + str3;
                        strArray2[index, 1] = "array";
                        strArray2[index, 2] = left;
                    }
                    else if (Strings.Mid(str6, 1, 1) == "5")
                    {
                    }
                }
            }
            left = Strings.Replace(strArray2[0, 2], find, "  ", 1, -1, CompareMethod.Binary);
            return (((("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + str3) + "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" + str3) + "<plist version=\"1.0\">" + str3) + left + "</plist>" + str3);
        }

        private static int[] ReadStream2Array(Stream stream)
        {
            List<int> intbuffer = new List<int>();
            while (true)
            {
                byte[] buffer = new byte[1000];
                int count = stream.Read(buffer, 0, 1000);
                if (count > 0)
                {
                    for (int i = 0; i < count; i++)
                    {
                        intbuffer.Add(Convert.ToInt32(buffer[i]));
                    }
                }
                else
                {
                    break;
                }
            }
            return intbuffer.ToArray();
        }

        private static string fixXMLString(string fixString)
        {
            fixString = Strings.Replace(fixString, "&", "&amp;", 1, -1, CompareMethod.Binary);
            fixString = Strings.Replace(fixString, "<", "&lt;", 1, -1, CompareMethod.Binary);
            fixString = Strings.Replace(fixString, ">", "&gt;", 1, -1, CompareMethod.Binary);
            return fixString;
        }
    }
}
